% => Tests para hamming
% Primer test de la catedra
testHamDef :- not(distHam([],[0],_)).
% Segundo test de la catedra
testHamNNoDef  :- findall(N,distHam([0,1],[0,1],N),T),permutation([0],T),!.
% Tercer test de la catedra
testHamNNoDef2 :- findall(N,distHam([0,1,0],[0,0,1],N),T),permutation(T,[2]),!.
% Cuarto test de la catedra
testHamNVarSol :- findall((X,Y,N),distHam([0,1,0],[X,Y,1],N),T),
					permutation(T,[(0,1,1),(0,0,2),(1,1,2),(1,0,3)]),!.
% Quinto test de la catedra
testHamSLNoDef :- findall(X,distHam([0,1,0],X,2),T),permutation(T,
					[ [0,0,1],[1,1,1],[1,0,0] ]),!.
% Sexto test de la catedra
testHamNo01 :- not(distHam([plp],[plp],_)).

% Test adicional: Probar con una lista con solo la cabeza instanciada
testHamInicIni :- findall(X,distHam([0,0,1],[0|X],2),T),
					permutation(T,[[1,0]]),!.

% Test adicional: Probar generar todos los pares (lista,dist. hamming)
testHamTodosP :- findall((X,Y),distHam([0,1],X,Y),T),
					permutation(T,[
						([0,0],1),([0,1],0),
						([1,0],2),([1,1],1)]),!.

% Test adicional: Revisar que si la lista en el medio tiene valores invalidos no
% unifique
testHamInvMedio :- not(distHam([0,1,0],[_X,plp|_Xs],_N)).

testsHam :-	testHamDef,
			testHamNNoDef,
			testHamNNoDef2,
			testHamNVarSol,
			testHamSLNoDef,
			testHamNo01,
			testHamInicIni,
			testHamTodosP,
			testHamInvMedio.

% => Tests para distancia de prefijo
% Primer test catedra
testPrefNNoDef :- findall(N,distPref([0,1,1],[0,1,1,1],N),T),
					permutation([1],T),!.
% Segundo test catedra
testPrefListaNoDefTot :- findall((X,Y,N),distPref([0,1,1],[0,1,X,Y],N),T),
							permutation(T,[(1,0,1),(1,1,1),(0,0,3),(0,1,3)]),!.

% Tercer test catedra
testPrefSegListaNoDef :- findall(X,distPref([0,1,1],X,2),T),
							permutation(T,[
								[0],[0, 1, 1, 0, 0], [0, 1, 1, 0, 1],
								[0, 1, 1, 1, 0], [0, 1, 1, 1, 1], [0,1,0] ]),!.

% Cuarto test catedra
testPrefNo01 :- not(distPref([plp],_Y,_N)).

% Test adicional: Generar todos los pares (lista,dist pref), acotando la longitud.
testPrefParesPred(X,Y) :- between(0,2,Y),distPref([],X,Y).
testPrefPares :- findall((X,Y),testPrefParesPred(X,Y),T),
					permutation(T,[
						([],0),([0],1),([1],1),([0,0],2),
						([1,0],2),([0,1],2),([1,1],2)]),!.

% Test adicional: Revisar que si la lista en el medio tiene valores invalidos no
% unifique
testInvMedio :- not(distPref([0,1,0],[_X,plp|_Xs],_N)).

testPref :- testPrefNNoDef,
			testPrefListaNoDefTot,
			testPrefSegListaNoDef,
			testPrefNo01,
			testPrefPares,
			testInvMedio.

% => Tests para distancia de edicion

% Primer test catedra
testEdDistNNoDef :- findall(N,distEd([0,0,1,1],[1,1,0],N),T),
						permutation(T,[3]),!.

% Segundo test catedra
testEdDistParcInit :- findall((X,Y,N),distEd([0,0,1],[1,1,X,Y],N),T),
						permutation(T,[(0,0,3),(0,1,2),(1,0,3),(1,1,3)]),!.

% Tercer test catedra
testEdDistParcInitHead :- findall(Xs,distEd([0,1,1,1],[1|Xs],2),T),
							permutation(T,[
								[1],
								[0, 1],
								[1, 0],
								[0, 1, 1],
								[1, 0, 1],
								[1, 1, 0],
								[0, 0, 1, 1],
								[0, 1, 0, 1],
								[0, 1, 1, 0],
								[1, 0, 1, 1],
								[1, 1, 0, 1],
								[1, 1, 1, 0],
								[1, 1, 1, 1],
								[0, 0, 1, 1, 1],
								[0, 1, 0, 1, 1],
								[0, 1, 1, 0, 1],
								[0, 1, 1, 1, 0],
								[0, 1, 1, 1, 1],
								[1, 0, 1, 1, 1] ]),!.

% Cuarto test catedra
testEdDistNo01 :- not(distEd([plp],_N,_T)).

% Quinto test catedra
testEdDistNo01LaRevancha :- not(distEd([0,1], [_X,plp|_Xs], _N)).

% Sexto test catedra
testEdDistNoSol :- not(distEd([0,1], [_X,0|_Xs], 0)).

% Septimo test catedra
testEdDistSolUniq :- findall((X,Xs),distEd([0,1], [X,1|Xs], 0),T),
						permutation(T,[(0,[])]),!.

% Test adicional: Generar todas las listas desde la vacia con edicion
testEdDistGenPred(X,Y) :- todosHasta(2,X),distEd([],X,Y).
testEdDistGen :- findall((X,Y),testEdDistGenPred(X,Y),T),
					permutation(T,[
						([],0),([0],1),([1],1),([0,0],2),
						([0,1],2),([1,0],2),([1,1],2)	
					]),!.

testEdDist :-	testEdDistNNoDef,
				testEdDistParcInit,
				testEdDistParcInitHead,
				testEdDistNo01,
				testEdDistNo01LaRevancha,
				testEdDistNoSol,
				testEdDistSolUniq,
				testEdDistGen.

tests :- testsHam,testPref,testEdDist.

main :- tests,write('TODOS LOS TESTS PASARON!!'),nl,halt.
main :- not(tests),write('FALLO ALGUN TEST!'),nl,halt.
